import { computed } from 'vue'
import { useDrag } from '@/utils'
import { MoveRange, DragState, DragBox, MovingData } from './type'

/** 移动位置 */
export default function useMove({
  box,
  state,
  onStart,
  onMoving,
  onEnd
}: {
  /** 盒子数据 */
  box: DragBox
  /** 状态 */
  state: DragState
  /** 移动开始 */
  onStart?: (e: MouseEvent | TouchEvent) => void | false
  /** 移动中 */
  onMoving?: (e: MouseEvent | TouchEvent, move: MovingData, state: DragState) => void
  /** 移动结束 */
  onEnd?: (e: MouseEvent | TouchEvent, data: DragState) => void
}) {
  // 移动范围
  let range: MoveRange | undefined

  /** 获取移动范围 */
  function getRange(): MoveRange {
    const { w, h, pw, ph, parent } = state
    // 最小坐标
    const min = parent ? 0 : -Infinity

    return {
      minX: min,
      maxX: parent ? pw - w : Infinity,
      minY: min,
      maxY: parent ? ph - h : Infinity
    }
  }

  return useDrag<{
    x: number
    y: number
  }>({
    zoom: computed(() => box.zoom),

    onStart(e) {
      state.active = true

      state.update()
      range = getRange()

      if (onStart?.(e) === false) return false

      const { x, y } = state

      return { x, y }
    },

    onMoving(e, move, { x: startX, y: startY }) {
      if (!range) return

      const { minX, maxX, minY, maxY } = range

      let x = startX + move.x
      let y = startY + move.y

      if (x > maxX) x = maxX
      if (x < minX) x = minX

      if (y > maxY) y = maxY
      if (y < minY) y = minY

      onMoving?.(e, { x, y, moveX: x - startX, moveY: y - startY }, state)
    },

    onEnd(e, moved) {
      moved && onEnd?.(e, state)
    }
  })
}
